/*
 *
 *  * Copyright (c) iwindplus Technologies Co., Ltd.2024-2030, All rights reserved.
 *
 *
 */

package com.iwindplus.base.http.client.manager;

import com.iwindplus.base.util.RestClientUtil;
import jakarta.annotation.Resource;
import java.util.List;
import java.util.Map;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.web.client.RestClient;
import org.springframework.web.multipart.MultipartFile;

/**
 * RestTemplate 工具管理器.
 *
 * @author zengdegui
 * @since 2025/02/15 21:45
 */
@Slf4j
@Getter
public class RestClientManager {

    @Resource
    private RestClient loadBalancedRestClient;

    @Resource
    private RestClient restClient;

    /**
     * get同步请求（参数拼接）.
     *
     * @param url             路径（必填）
     * @param header          请求头（可选）
     * @param param           参数（可选）
     * @param clazz           返回值类型
     * @param useLoadBalanced 是否使用负载均衡
     * @param <T>             泛型
     * @return T
     */
    public <T> T httpGet(String url, Map<String, String> header, Map<String, Object> param, Class<T> clazz, boolean useLoadBalanced) {
        return RestClientUtil.httpGet(getRestClient(useLoadBalanced), url, header, param, clazz);
    }


    /**
     * get同步请求（参数拼接）.
     *
     * @param url             路径（必填）
     * @param header          请求头（可选）
     * @param param           参数（可选）
     * @param typeRef         返回值类型
     * @param useLoadBalanced 是否使用负载均衡
     * @param <T>             泛型
     * @return T
     */
    public <T> T httpGet(String url, Map<String, String> header, Map<String, Object> param, ParameterizedTypeReference<T> typeRef,
        boolean useLoadBalanced) {
        return RestClientUtil.httpGet(getRestClient(useLoadBalanced), url, header, param, typeRef);
    }

    /**
     * post同步请求（json）.
     *
     * @param url             路径（必填）
     * @param header          请求头（可选）
     * @param json            参数（必填）
     * @param clazz           返回值类型
     * @param useLoadBalanced 是否使用负载均衡
     * @param <T>             泛型
     * @return T
     */
    public <T> T httpPostByJson(String url, Map<String, String> header, String json, Class<T> clazz, boolean useLoadBalanced) {
        return RestClientUtil.httpPostByJson(getRestClient(useLoadBalanced), url, header, json, clazz);
    }

    /**
     * post同步请求（json）.
     *
     * @param url             路径（必填）
     * @param header          请求头（可选）
     * @param json            参数（必填）
     * @param typeRef         返回值类型
     * @param useLoadBalanced 是否使用负载均衡
     * @param <T>             泛型
     * @return T
     */
    public <T> T httpPostByJson(String url, Map<String, String> header, String json, ParameterizedTypeReference<T> typeRef, boolean useLoadBalanced) {
        return RestClientUtil.httpPostByJson(getRestClient(useLoadBalanced), url, header, json, typeRef);
    }

    /**
     * post同步请求（FormBody表单）.
     *
     * @param url             路径（必填）
     * @param header          请求头（可选）
     * @param param           参数（可选）
     * @param clazz           返回值类型
     * @param useLoadBalanced 是否使用负载均衡
     * @param <T>             泛型
     * @return T
     */
    public <T> T httpPostByForm(String url, Map<String, String> header, Map<String, Object> param, Class<T> clazz, boolean useLoadBalanced) {
        return RestClientUtil.httpPostByForm(getRestClient(useLoadBalanced), url, header, param, clazz);
    }

    /**
     * post同步请求（FormBody表单）.
     *
     * @param url             路径（必填）
     * @param header          请求头（可选）
     * @param param           参数（可选）
     * @param typeRef         返回值类型
     * @param useLoadBalanced 是否使用负载均衡
     * @param <T>             泛型
     * @return T
     */
    public <T> T httpPostByForm(String url, Map<String, String> header, Map<String, Object> param, ParameterizedTypeReference<T> typeRef,
        boolean useLoadBalanced) {
        return RestClientUtil.httpPostByForm(getRestClient(useLoadBalanced), url, header, param, typeRef);
    }

    /**
     * post同步请求（MultipartBody表单）.
     *
     * @param url             路径（必填）
     * @param header          请求头（可选）
     * @param param           参数（可选）
     * @param files           文件集合（可选）
     * @param clazz           返回值类型
     * @param useLoadBalanced 是否使用负载均衡
     * @param <T>             泛型
     * @return T
     */
    public <T> T httpPostByMultipart(String url, Map<String, String> header, Map<String, Object> param, List<MultipartFile> files, Class<T> clazz,
        boolean useLoadBalanced) {
        return RestClientUtil.httpPostByMultipart(getRestClient(useLoadBalanced), url, header, param, files, clazz);
    }

    /**
     * post同步请求（MultipartBody表单）.
     *
     * @param url             路径（必填）
     * @param header          请求头（可选）
     * @param param           参数（可选）
     * @param files           文件集合（可选）
     * @param typeRef         返回值类型
     * @param useLoadBalanced 是否使用负载均衡
     * @param <T>             泛型
     * @return T
     */
    public <T> T httpPostByMultipart(String url, Map<String, String> header, Map<String, Object> param, List<MultipartFile> files,
        ParameterizedTypeReference<T> typeRef, boolean useLoadBalanced) {
        return RestClientUtil.httpPostByMultipart(getRestClient(useLoadBalanced), url, header, param, files, typeRef);
    }

    /**
     * put同步请求（json）.
     *
     * @param url             路径（必填）
     * @param header          请求头（可选）
     * @param json            参数（必填）
     * @param clazz           返回值类型
     * @param useLoadBalanced 是否使用负载均衡
     * @param <T>             泛型
     * @return T
     */
    public <T> T httpPutByJson(String url, Map<String, String> header, String json, Class<T> clazz, boolean useLoadBalanced) {
        return RestClientUtil.httpPutByJson(getRestClient(useLoadBalanced), url, header, json, clazz);
    }

    /**
     * put同步请求（json）.
     *
     * @param url             路径（必填）
     * @param header          请求头（可选）
     * @param json            参数（必填）
     * @param typeRef         返回值类型
     * @param useLoadBalanced 是否使用负载均衡
     * @param <T>             泛型
     * @return T
     */
    public <T> T httpPutByJson(String url, Map<String, String> header, String json, ParameterizedTypeReference<T> typeRef, boolean useLoadBalanced) {
        return RestClientUtil.httpPutByJson(getRestClient(useLoadBalanced), url, header, json, typeRef);
    }

    /**
     * put同步请求（FormBody表单）.
     *
     * @param url             路径（必填）
     * @param header          请求头（可选）
     * @param param           参数（可选）
     * @param clazz           返回值类型
     * @param useLoadBalanced 是否使用负载均衡
     * @param <T>             泛型
     * @return T
     */
    public <T> T httpPutByForm(String url, Map<String, String> header, Map<String, Object> param, Class<T> clazz, boolean useLoadBalanced) {
        return RestClientUtil.httpPutByForm(getRestClient(useLoadBalanced), url, header, param, clazz);
    }

    /**
     * put同步请求（FormBody表单）.
     *
     * @param url             路径（必填）
     * @param header          请求头（可选）
     * @param param           参数（可选）
     * @param typeRef         返回值类型
     * @param useLoadBalanced 是否使用负载均衡
     * @param <T>             泛型
     * @return T
     */
    public <T> T httpPutByForm(String url, Map<String, String> header, Map<String, Object> param, ParameterizedTypeReference<T> typeRef,
        boolean useLoadBalanced) {
        return RestClientUtil.httpPutByForm(getRestClient(useLoadBalanced), url, header, param, typeRef);
    }

    /**
     * put同步请求（MultipartBody表单）.
     *
     * @param url             路径（必填）
     * @param header          请求头（可选）
     * @param param           参数（可选）
     * @param files           文件集合（可选）
     * @param clazz           返回值类型
     * @param useLoadBalanced 是否使用负载均衡
     * @param <T>             泛型
     * @return T
     */
    public <T> T httpPutByMultipart(String url, Map<String, String> header, Map<String, Object> param, List<MultipartFile> files, Class<T> clazz,
        boolean useLoadBalanced) {
        return RestClientUtil.httpPutByMultipart(getRestClient(useLoadBalanced), url, header, param, files, clazz);
    }

    /**
     * put同步请求（MultipartBody表单）.
     *
     * @param url             路径（必填）
     * @param header          请求头（可选）
     * @param param           参数（可选）
     * @param files           文件集合（可选）
     * @param typeRef         返回值类型
     * @param useLoadBalanced 是否使用负载均衡
     * @param <T>             泛型
     * @return T
     */
    public <T> T httpPutByMultipart(String url, Map<String, String> header, Map<String, Object> param, List<MultipartFile> files,
        ParameterizedTypeReference<T> typeRef, boolean useLoadBalanced) {
        return RestClientUtil.httpPutByMultipart(getRestClient(useLoadBalanced), url, header, param, files, typeRef);
    }

    /**
     * delete同步请求（参数拼接）.
     *
     * @param url             路径（必填）
     * @param header          请求头（可选）
     * @param param           参数（可选）
     * @param clazz           返回值类型
     * @param useLoadBalanced 是否使用负载均衡
     * @param <T>             泛型
     * @return T
     */
    public <T> T httpDelete(String url, Map<String, String> header, Map<String, Object> param, Class<T> clazz, boolean useLoadBalanced) {
        return RestClientUtil.httpDelete(getRestClient(useLoadBalanced), url, header, param, clazz);
    }

    /**
     * delete同步请求（参数拼接）.
     *
     * @param url             路径（必填）
     * @param header          请求头（可选）
     * @param param           参数（可选）
     * @param typeRef         返回值类型
     * @param useLoadBalanced 是否使用负载均衡
     * @param <T>             泛型
     * @return T
     */
    public <T> T httpDelete(String url, Map<String, String> header, Map<String, Object> param, ParameterizedTypeReference<T> typeRef,
        boolean useLoadBalanced) {
        return RestClientUtil.httpDelete(getRestClient(useLoadBalanced), url, header, param, typeRef);
    }

    /**
     * delete同步请求（json）.
     *
     * @param url             路径（必填）
     * @param header          请求头（可选）
     * @param json            参数（必填）
     * @param clazz           返回值类型
     * @param useLoadBalanced 是否使用负载均衡
     * @param <T>             泛型
     * @return T
     */
    public <T> T httpDeleteByJson(String url, Map<String, String> header, String json, Class<T> clazz, boolean useLoadBalanced) {
        return RestClientUtil.httpDeleteByJson(getRestClient(useLoadBalanced), url, header, json, clazz);
    }

    /**
     * delete同步请求（json）.
     *
     * @param url             路径（必填）
     * @param header          请求头（可选）
     * @param json            参数（必填）
     * @param typeRef         返回值类型
     * @param useLoadBalanced 是否使用负载均衡
     * @param <T>             泛型
     * @return T
     */
    public <T> T httpDeleteByJson(String url, Map<String, String> header, String json, ParameterizedTypeReference<T> typeRef,
        boolean useLoadBalanced) {
        return RestClientUtil.httpDeleteByJson(getRestClient(useLoadBalanced), url, header, json, typeRef);
    }

    /**
     * delete同步请求（FormBody表单）.
     *
     * @param url             路径（必填）
     * @param header          请求头（可选）
     * @param param           参数（可选）
     * @param clazz           返回值类型
     * @param useLoadBalanced 是否使用负载均衡
     * @param <T>             泛型
     * @return T
     */
    public <T> T httpDeleteByForm(String url, Map<String, String> header, Map<String, Object> param, Class<T> clazz, boolean useLoadBalanced) {
        return RestClientUtil.httpDelete(getRestClient(useLoadBalanced), url, header, param, clazz);
    }

    /**
     * delete同步请求（FormBody表单）.
     *
     * @param url             路径（必填）
     * @param header          请求头（可选）
     * @param param           参数（可选）
     * @param typeRef         返回值类型
     * @param useLoadBalanced 是否使用负载均衡
     * @param <T>             泛型
     * @return T
     */
    public <T> T httpDeleteByForm(String url, Map<String, String> header, Map<String, Object> param, ParameterizedTypeReference<T> typeRef,
        boolean useLoadBalanced) {
        return RestClientUtil.httpDelete(getRestClient(useLoadBalanced), url, header, param, typeRef);
    }

    private RestClient getRestClient(boolean useLoadBalanced) {
        return useLoadBalanced ? this.loadBalancedRestClient : this.restClient;
    }
}
